package com.adcc.loadsheet.billing.service.impl;

import com.adcc.loadsheet.billing.configuration.SystemConfig;
import com.adcc.loadsheet.billing.entity.BillingBillEntity;
import com.adcc.loadsheet.billing.mapper.mysql.BillingBillEntityMapper;
import com.adcc.loadsheet.billing.security.UserInfo;
import com.adcc.loadsheet.billing.service.BillingBillService;
import com.adcc.loadsheet.billing.util.*;
import com.adcc.loadsheet.billing.vo.BillingBillEntityVO;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 计费帐单service实现类
 */
@Service
public class BillingBillServiceImpl extends BasisServiceImpl implements BillingBillService {

    @Autowired
    BillingBillEntityMapper billingBillEntityMapper;

    @Autowired
    SystemConfig systemConfig;

    int index = 1;

    //按主键查询计费帐单
    @Override
    public BillingBillEntity selectByPrimaryKey(Integer id){
        BillingBillEntity billingBillEntity = billingBillEntityMapper.selectByPrimaryKey(id);
        return billingBillEntity;
    }

    //编辑计费帐单
    @Override
    @Transactional(transactionManager = "mysqlTransactionManager")
    public void edit(BillingBillEntity billingBillEntity,MultipartFile executeFile){
        try{
            UserInfo user = userContext.getCurrentUser();
            String userName = user != null ? user.getUsername() : "SYSTEM";

            billingBillEntity.setUpdateAt(DateTimeUtil.getNowDate());
            billingBillEntity.setUpdateUser(userName);

            if(billingBillEntity.getId() == null){
                billingBillEntity.setCreateAt(DateTimeUtil.getNowDate());
                billingBillEntity.setCreateUser(userName);
                billingBillEntityMapper.insert(billingBillEntity);
                //由JOB执行添加，日志添加至JOB日志，此处不需要再记录操作日志
            }else {
                if(executeFile != null){
                    String fileName = executeFile.getOriginalFilename();

                    //记录操作日志
                    BillingBillEntity oldBillingBillEntity = billingBillEntityMapper.selectByPrimaryKey(billingBillEntity.getId());
                    String oldExecuteFileName = Strings.isNullOrEmpty(oldBillingBillEntity.getExecuteFileName()) ? "" : oldBillingBillEntity.getExecuteFileName();
                    if(!oldExecuteFileName.equals(fileName)) {
                        String logContent = "修改" + oldBillingBillEntity.getContractUserAbbrev() + oldBillingBillEntity.getBillingCycle() + "月账单明细：执行账单文档由“" + oldExecuteFileName + "”修改为“" + fileName + "”";
                        LogUtil.operationLog(SystemOperationLogType.BillingList_Operation.ordinal(), logContent, user.getUsername());
                    }

                    billingBillEntity.setExecuteFileName(fileName);
                    //转存到指定文件夹内
                    //执行账单明细路径+文件名称
                    String filePathStr =  billingBillEntity.getBillingCycle() + "//" + UUID.randomUUID().toString() + fileName.substring(fileName.indexOf("."));
                    billingBillEntity.setExecuteFile(filePathStr);
                    File file = FileUtil.multipartFileToFile(executeFile);
                    FileUtil.copyFile(file, new File(systemConfig.getAutomaticProcessingBillsPath() + filePathStr));

                    //删除文件
                    file.delete();
                }
                billingBillEntityMapper.update(billingBillEntity);
            }
        }catch (Exception e){

        }
    }

    //查询计费帐单
    @Override
    public PageInfo<BillingBillEntityVO> selectBillingBillForPage(Map<String, Object> map){
        Integer pageNum = Integer.valueOf(map.get("pageNum").toString());
        Integer pageSize = Integer.valueOf(map.get("pageSize").toString());
        PageHelper.startPage(pageNum, pageSize);
        Page<BillingBillEntity> entityPage = (Page<BillingBillEntity>) billingBillEntityMapper.select(map);
        Page<BillingBillEntityVO> voPage = new Page<>(pageNum, pageSize);
        voPage.setPages(entityPage.getPages());
        voPage.setTotal(entityPage.getTotal());
        index = (pageNum - 1) * pageSize + 1;
        entityPage.stream().forEach(entity -> voPage.add(entity.toVO(index++)));
        return new PageInfo<>(voPage);
    }

    //下载文件
    @Override
    public String exportFile(String billingFileName,String filePath,HttpServletResponse response){
        String result = "OK";
        try{
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            // 下载文件能正常显示中文
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(billingFileName, "UTF-8"));
            // 实现文件下载
            OutputStream out = response.getOutputStream();
            byte[] buffer = new byte[1024];
            FileInputStream fis = new FileInputStream(systemConfig.getAutomaticProcessingBillsPath() + filePath);
            BufferedInputStream bis = new BufferedInputStream(fis);
            int i = bis.read(buffer);
            while (i != -1) {
                out.write(buffer, 0, i);
                i = bis.read(buffer);
            }
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            out.flush();
            out.close();
        }catch (Exception ex){
            result = ex.getMessage();
        }
        return result;
    }

    //批量编辑计费账单（执行金额和备注）
    @Override
    @Transactional(transactionManager = "mysqlTransactionManager")
    public void editExecute(List<Object> billingBillEntityVOs){
        try{
            UserInfo user = userContext.getCurrentUser();
            BillingBillEntity billingBillEntity;
            String logContent = "";     //日志内容
            for(Object object : billingBillEntityVOs){
                logContent = "";
                Map<String,Object> billingBillEntityVOMap = (Map<String,Object>)object;
                billingBillEntity = billingBillEntityMapper.selectByPrimaryKey(Integer.valueOf(billingBillEntityVOMap.get("id").toString()));
                String oldExecuteAmount = billingBillEntity.getExecuteAmount() == null ? "" : billingBillEntity.getExecuteAmount().toString();
                String newExecuteAmount = billingBillEntityVOMap.get("executeAmount").toString();
                //记录操作日志
                if(!oldExecuteAmount.equals(newExecuteAmount)) {
                    logContent += Strings.isNullOrEmpty(logContent) ? "修改" + billingBillEntity.getContractUserAbbrev() + billingBillEntity.getBillingCycle() + "月账单明细：" : "";
                    logContent += "执行金额由“" + oldExecuteAmount + "”修改为“" + newExecuteAmount + "”";
                }
                String oldRemark = Strings.isNullOrEmpty(billingBillEntity.getRemark()) ? "" : billingBillEntity.getRemark();
                String newRemark = billingBillEntityVOMap.get("remark").toString();
                if(!oldRemark.equals(newRemark)) {
                    logContent += Strings.isNullOrEmpty(logContent) ? "修改" + billingBillEntity.getContractUserAbbrev() + billingBillEntity.getBillingCycle() + "月账单明细：：备注由“" + oldRemark + "”修改为“" + newRemark + "”" : "，备注由“" + oldRemark + "”修改为“" + newRemark + "”";
                }
                if(!Strings.isNullOrEmpty(logContent)){
                    LogUtil.operationLog(SystemOperationLogType.BillingList_Operation.ordinal(), logContent, user.getUsername());
                }

                //编辑信息并保存
                billingBillEntity.setExecuteAmount(Strings.isNullOrEmpty(newExecuteAmount) ? null : new BigDecimal(newExecuteAmount));
                billingBillEntity.setRemark(newRemark);
                billingBillEntity.setUpdateAt(DateTimeUtil.getNowDate());
                billingBillEntity.setUpdateUser(user.getUsername());
                billingBillEntityMapper.update(billingBillEntity);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //导出excel
    @Override
    public void excel(String billingCycle,Integer contractUserId,HttpServletResponse response){
        HSSFWorkbook hssfWorkbook = getHSSFWorkbook(billingCycle,contractUserId);
        ExcelUtil.returnClient(response, "计费账单数据.xls", hssfWorkbook);
    }
    //填充Excel
    private HSSFWorkbook getHSSFWorkbook(String billingCycle,Integer contractUserId){
        String[] titles = new String[]{"序号", "用户名称","账单周期", "明细文档", "账单金额", "执行金额","执行账单文档","备注"};
        Map<String, Object> paramMap = Maps.newConcurrentMap();
        paramMap.put("billingCycle",billingCycle);
        if(contractUserId != null){
            paramMap.put("contractUserId",contractUserId);
        }
        List<BillingBillEntity> details = billingBillEntityMapper.select(paramMap);
        String[][] values = new String[details.size()][titles.length];
        if (details != null && details.size() > 0) {
            BillingBillEntity entity;
            int index = 1;
            for (int i = 0; i < details.size(); i++) {
                entity = details.get(i);
                values[i][0] = (index++) + "";
                values[i][1] = entity.getContractUserAbbrev();
                values[i][2] = entity.getBillingCycle();
                values[i][3] = entity.getBillingFileName();
                values[i][4] = entity.getBillingAmount();
                values[i][5] = entity.getExecuteAmount() == null ? "" : entity.getExecuteAmount().toString();
                values[i][6] = entity.getExecuteFileName();
                values[i][7] = entity.getRemark();
            }
        }
        return ExcelUtil.getHSSFWorkbook("导出计费账单数据", titles, values);
    }
}